package com.meeting.common;

import com.demo.DemoController;
import com.demo.DemoIndexController;
import com.demo.UserController;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.plugin.cron4j.Cron4jPlugin;
import com.jfinal.swagger.config.SwaggerConfig;
import com.jfinal.swagger.config.SwaggerRoute;
import com.jfinal.swagger.enums.InType;
import com.jfinal.weixin.sdk.api.ApiConfig;
import com.jfinal.weixin.sdk.api.ApiConfigKit;
import com.jfinal.wxaapp.WxaConfig;
import com.jfinal.wxaapp.WxaConfigKit;
import com.meeting.blog.BlogController;
import com.meeting.common.model._MappingKit;
import com.meeting.index.IndexController;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.template.Engine;
import com.meeting.y.controller.*;
import com.meeting.y.interceptor.CurrentUserInterceptor;
import com.meeting.y.task.RemindHealth;
import com.meeting.y.task.RemindMonitor;

/**
 * 本 demo 仅表达最为粗浅的 jfinal 用法，更为有价值的实用的企业级用法
 * 详见 JFinal 俱乐部: http://jfinal.com/club
 * 
 * API 引导式配置
 */
public class DemoConfig extends JFinalConfig {
	
	static Prop p;
	
	/**
	 * 启动入口，运行此 main 方法可以启动项目，此 main 方法可以放置在任意的 Class 类定义中，不一定要放于此
	 */
	public static void main(String[] args) {

		UndertowServer.start(DemoConfig.class);
	}
	
	/**
	 * PropKit.useFirstFound(...) 使用参数中从左到右最先被找到的配置文件
	 * 从左到右依次去找配置，找到则立即加载并立即返回，后续配置将被忽略
	 */
	static void loadConfig() {
		if (p == null) {
			p = PropKit.useFirstFound("demo-config-pro.txt", "demo-config-dev.txt");
		}
	}
	
	/**
	 * 配置常量
	 */
	public void configConstant(Constants me) {
		loadConfig();
		
		me.setDevMode(p.getBoolean("devMode", false));
		
		/**
		 * 支持 Controller、Interceptor、Validator 之中使用 @Inject 注入业务层，并且自动实现 AOP
		 * 注入动作支持任意深度并自动处理循环注入
		 */
		me.setInjectDependency(true);
		
		// 配置对超类中的属性进行注入
		me.setInjectSuperClass(true);
	}
	
	/**
	 * 配置路由
	 */
	public void configRoute(Routes me) {
		me.add("/", IndexController.class, "/index");	// 第三个参数为该Controller的视图存放路径
		me.add("/blog", BlogController.class);			// 第三个参数省略时默认与第一个参数值相同，在此即为 "/blog"

		me.add("/y/setm", SetYmeetingAdminController.class);
		me.add("/y/m", YmeetingAdminController.class);
		me.add("/api/meeting", YmeetingController.class);
		me.add("/api/paper", YpaperController.class);
		me.add("/api/toy", YtoyController.class);
		me.add("/y/admin", UploadClassesController.class);
		me.add("/y/export", YmeetingExportController.class);


		me.add("/user", UserController.class);
		me.add("/demo", DemoController.class);
		me.add("/demoindex", DemoIndexController.class);
		me.add("/wxa/user", WxaUserApiController.class);

		// 配置Swagger UI访问路由
		me.add(new SwaggerRoute());
	}
	
	public void configEngine(Engine me) {
		me.addSharedFunction("/common/_layout.html");
		me.addSharedFunction("/common/_paginate.html");
	}
	
	/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {
		// 配置 druid 数据库连接池插件
		DruidPlugin druidPlugin = new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password").trim());
		me.add(druidPlugin);
		
		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(druidPlugin);
		// 所有映射在 MappingKit 中自动化搞定
		_MappingKit.mapping(arp);
		com.meeting.y.model._MappingKit.mapping(arp);
		me.add(arp);

		/*DruidPlugin meeting_druidPlugin = new DruidPlugin(p.get("meeting.url"), p.get("meeting.username"), p.get("meeting.password").trim());
		me.add(meeting_druidPlugin);
		// 配置ActiveRecord插件
		ActiveRecordPlugin meeting_arp = new ActiveRecordPlugin("meeting",meeting_druidPlugin);
		// 所有映射在 MappingKit 中自动化搞定
		_MappingKit.mapping(meeting_arp);
		me.add(meeting_arp);*/


		ApiConfig ac = new ApiConfig();
		// 配置微信 API 相关参数
		ac.setToken(PropKit.get("token"));
		ac.setAppId(PropKit.get("appId"));
		ac.setAppSecret(PropKit.get("appSecret"));

		/**
		 *  是否对消息进行加密，对应于微信平台的消息加解密方式：
		 *  1：true进行加密且必须配置 encodingAesKey
		 *  2：false采用明文模式，同时也支持混合模式
		 */
		ac.setEncryptMessage(PropKit.getBoolean("encryptMessage", false));
		ac.setEncodingAesKey(PropKit.get("encodingAesKey", "setting it in config file"));

		/**
		 * 多个公众号时，重复调用ApiConfigKit.putApiConfig(ac)依次添加即可，第一个添加的是默认。
		 */
		ApiConfigKit.putApiConfig(ac);


		WxaConfig wc = new WxaConfig();
		wc.setAppId(PropKit.get("appId"));
		wc.setAppSecret(PropKit.get("appSecret"));
		WxaConfigKit.setWxaConfig(wc);

		Cron4jPlugin cp = new Cron4jPlugin();
		if("true".equals(p.get("cornenable_health"))){
			//定时任务未启动，默认启动
			cp.addTask("1 9,12 * * * ", new RemindHealth(p.get("corn.remind.url")));
		}
		if("true".equals(p.get("cornenable_monitor"))){
			//定时任务未启动，默认启动
			cp.addTask("1 8,9,17 * * * ", new RemindMonitor(p.get("corn.remind.monitor.url")));
		}
		me.add(cp);

	}
	
	public static DruidPlugin createDruidPlugin() {
		loadConfig();
		
		return new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password").trim());
	}
	
	/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {
		me.add(new CurrentUserInterceptor());
	}
	
	/**
	 * 配置处理器
	 */
	public void configHandler(Handlers me) {
		me.add(new ContextPathHandler("ctx"));
	}

	/**
	 * JFinal启动完成后的操作
	 */
	@Override
	public void onStart() {
		// 配置添加全局参数(如token，非必需)
		SwaggerConfig.addGlobalParam("x-access-token", "token令牌", "string", "jfinal-awesome-token", true, "", InType.HEADER);
	}
}
